﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using StockFinder.Model;

namespace StockFinder.Indicators.Day.ClosePrice
{
    public class ExponentialMovingAverageClosePriceDayIndicator : BaseDayIndicator
    {
        public ExponentialMovingAverageClosePriceDayIndicator(int lookbackPeriod, string indicatorName) : base(lookbackPeriod, indicatorName)
        {
        }

        public override void ApplyIndicator(List<DailyPrice> prices)
        {
            if (!Initialize(prices)) return;

            var orderedPrices = prices.OrderBy(p => p.PriceDate);
            DailyPrice currentPrice;
            DailyPrice previousPrice;

            var pricesArray = orderedPrices.ToArray();
            IEnumerable<DailyPrice> skippedPrices;
            IEnumerable<DailyPrice> takenPrices;

            var pricesCount = orderedPrices.Count();

            var smoothingConstant = 2m / ((decimal)LookbackPeriod + 1);

            //start from 50
            for (var i = (LookbackPeriod - 1); i < pricesCount; i++)
            {
                currentPrice = pricesArray[i];

                if (i == (LookbackPeriod - 1))
                {
                    /* sma for first */

                    var numberToSkip = (i + 1) - LookbackPeriod;

                    skippedPrices = pricesArray.Skip(numberToSkip);

                    takenPrices = skippedPrices.Take(LookbackPeriod);

                    currentPrice.DayIndicators[IndicatorName] = takenPrices.Average(p => p.AdjustedClose);
                }

                if (i > (LookbackPeriod - 1))
                {
                    /* EMA for rest */

                    previousPrice = pricesArray[i - 1];

                    var previousValue = previousPrice.DayIndicators[IndicatorName];

                    currentPrice.DayIndicators[IndicatorName] = smoothingConstant *
                                                                (currentPrice.AdjustedClose - previousValue) +
                                                                previousValue;
                }
            }
        }
    }
}
